#include <sstream>

#include "../../include/CLink/database/DatabaseManager.h"
#include "../../include/CLink/database/ORM.h"


namespace CLink {
namespace Db {

Model::Model(std::shared_ptr<DatabaseManager> _db)
    :_db(_db)
{

}

bool Model::save() 
{
    auto builder = _db->getQueryBuilder();
    builder.from(getTableName());

    try {
        if (!validate()) {
            return false;
        }
        
        if (_isNewRecord) {
            // 插入新记录
            builder.insert(_attributes);
            auto result = _db->execute(builder);
            if (result > 0) {
                // 获取自增主键
                /*if (auto it = _attributes.find(getPrimaryKey()); it == _attributes.end()) {
                    _attributes[getPrimaryKey()] = std::to_string(_db->lastInsertId());
                }*/
                _isNewRecord = false;
                return true;
            }
        } else {
            // 更新现有记录
            auto primaryKey = getPrimaryKey();
            auto id = _attributes[primaryKey];
            
            // 从更新数据中移除主键
            auto updateData = _attributes;
            updateData.erase(primaryKey);
            
            builder.update(updateData)
                  .where(primaryKey, id);
            
            return _db->execute(builder) > 0;
        }
    } catch (const DatabaseException& e) {
        _errors.push_back("Save failed: " + std::string(e.what()));
        return false;
    }
    
    return false;
}

bool Model::update(const std::map<std::string, std::string>& attributes) {
    // 更新属性
    for (const auto& [key, value] : attributes) {
        setAttribute(key, value);
    }
    
    return save();
}

bool Model::remove() {
    if (_isNewRecord) {
        _errors.push_back("Cannot delete new record");
        return false;
    }
    
    try {
        auto builder = _db->getQueryBuilder();
        builder.from(getTableName());
        builder.del()
               .where(getPrimaryKey(), _attributes[getPrimaryKey()]);
        
        return _db->execute(builder) > 0;
    } catch (const DatabaseException& e) {
        _errors.push_back("Delete failed: " + std::string(e.what()));
        return false;
    }
}

// 这些方法已移至头文件中作为模板方法实现

// 模板函数已移至头文件中实现

void Model::setAttribute(const std::string& key, const std::string& value) {
    _attributes[key] = value;
}

std::string Model::getAttribute(const std::string& key) const {
    auto it = _attributes.find(key);
    return it != _attributes.end() ? it->second : "";
}

bool Model::hasAttribute(const std::string& key) const {
    return _attributes.find(key) != _attributes.end();
}

bool Model::validate() {
    _errors.clear();
    
    for (const auto& rule : getValidationRules()) {
        if (!hasAttribute(rule.field)) {
            if (std::find_if(rule.validators.begin(), rule.validators.end(),
                            [](const auto& v) { return v(""); }) == rule.validators.end()) {
                _errors.push_back(rule.message);
            }
            continue;
        }
        
        const auto& value = getAttribute(rule.field);
        if (std::find_if(rule.validators.begin(), rule.validators.end(),
                        [&value](const auto& v) { return v(value); }) == rule.validators.end()) {
            _errors.push_back(rule.message);
        }
    }
    
    return _errors.empty();
}

std::vector<std::string> Model::getErrors() const {
    return _errors;
}

// 表操作方法已移至头文件中作为模板方法实现

} // namespace Db
} // namespace CLink